#include <iostream>
#include <memory>
#include <vector>
#include <functional>
#include <unordered_map>
#include <cstdint>
#include <unistd.h>
using TaskFunc = std::function<void()>;
using RealeaseFunc = std::function<void()>;
class TimerTask{ // 对象什么时候执行什么任务
private:
    uint64_t _id; // 定时器对象id
    uint32_t _timeout; // 超时时间
    TaskFunc _callback; // 定时器要执行的定时任务
    bool _canceled;// false 没有取消
    RealeaseFunc _release; // 删除TimerWheel中的定时器对象信息
public:
    TimerTask(uint64_t id,uint32_t timeout,const TaskFunc& callback,bool cancel = false):_id(id),_timeout(timeout),_callback(callback),_canceled(cancel){}
    ~TimerTask(){
        if(!_canceled)
            _callback();
        _release();
    }
    inline void ChangeCancel(){_canceled = !_canceled;}
    void SetRelease(const RealeaseFunc& cb){_release = cb;}
    inline uint32_t GetTimeout(){return _timeout;}
};

class TimerWheel{
private:
    using WeakTask = std::weak_ptr<TimerTask>; // 通过weak_ptr构造shared_ptr，保证每个Task能共享同一个引用计数。
    using PtrTask = std::shared_ptr<TimerTask>;
    int _tick; // 当前的秒针，走到哪里就是放哪里
    int _capacity; // 表盘的最大数量，就是最大延迟时间
    std::vector<std::vector<PtrTask>> _wheel;
    std::unordered_map<uint64_t,WeakTask> _timers;
private:
    inline void RemoveTimerInfo(uint64_t id){
        if(_timers.find(id) != _timers.end()){
            _timers.erase(id);
        }
    }
public:
    TimerWheel():_tick(0),_capacity(60),_wheel(_capacity){}
    // Add
    void TimerAdd(uint64_t id,uint32_t timeout,const TaskFunc& callback);
    // mod 刷新定时任务
    void TimerRefresh(uint64_t id);
    void RunTimerTask();
    void TimerCancel(uint64_t id);
};

void TimerWheel::TimerAdd(uint64_t id,uint32_t timeout,const TaskFunc& callback){
    PtrTask pt(new TimerTask(id,timeout,callback));
    pt->SetRelease(std::bind(&TimerWheel::RemoveTimerInfo,this,id));
    _timers.insert({id,WeakTask(pt)});
    // 添加到轮子中
    _wheel[(timeout+_tick)%_capacity].emplace_back(pt);
}
void TimerWheel::TimerRefresh(uint64_t id){
    // 通过保存的定时器对象的weakptr构造一个shared_ptr中
    if(_timers.find(id) == _timers.end()){
        return;
    }
    auto WeakPtr = _timers.at(id);
    PtrTask pt = WeakPtr.lock(); // 获取weak_ptr管理的shared_ptr
    int delay = pt->GetTimeout();
    _wheel[(_tick + delay)%_capacity].emplace_back(pt);
}
void TimerWheel::RunTimerTask(){
    _tick = (_tick + 1) % _capacity;
    //走到哪里释放哪里
    _wheel[_tick].clear();
}
void TimerWheel::TimerCancel(uint64_t id){
    if(_timers.find(id) == _timers.end()) return;
    auto pt = _timers.at(id).lock(); // 拿到shared_ptr
    if(pt) pt->ChangeCancel(); 
}
class Test{
public:
    Test(){
        std::cout << "构造" << std::endl;
    }
    ~Test(){
        printf("析构\n");
    }

};
void Del(Test* t){
    delete t;
}
int main(){
    TimerWheel tw;
    Test * t = new Test();
    tw.TimerAdd(12,5,std::bind(Del,t));

    for(int i = 0; i < 5;i++){
        tw.TimerRefresh(12);
        tw.RunTimerTask();
        printf("刷新定时任务，需要+5s销毁\n");
        sleep(1);
    }
    tw.TimerCancel(12);
    while (true)
    {
        /* code */
        sleep(1);
        printf("----------\n");
        tw.RunTimerTask();

    }
    
    return 0;
}